package com.shunda.ysdgj.common.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.beans.BeanUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

// Excel表格数据导入数据库 M是Entity T是Vo
public class EasyExcelListener<M, T> implements ReadListener<T> {

    private final Class<M> clazzM;
    private final IService<M> baseService;
    private static final int BATCH_COUNT = 100;
    private List<M> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    public EasyExcelListener(IService<M> baseService, Class<M> clazzM) {
        this.baseService = baseService;
        this.clazzM = clazzM;
    }

    // 从Excel表格的第二行开始读取，每读取一行调用一次invoke
    @Override
    public void invoke(T t, AnalysisContext analysisContext) {
        try {
            M m = clazzM.getDeclaredConstructor().newInstance();
            BeanUtils.copyProperties(t, m);
            cachedDataList.add(m);
            // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
            if (cachedDataList.size() >= BATCH_COUNT) {
                saveData();
                // 存储完成清理 list
                cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
            }
        } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();
    }

    private void saveData() {
        baseService.saveBatch(cachedDataList);
    }
}
